<?php
/**
 * Created by PhpStorm.
 * User: liu
 * Date: 17-11-26
 * Time: 下午1:08
 */

namespace vola\model\connection;

use vola\model\Connection;
use vola\Container;

class PdoConnection extends Connection
{

    public $pdo;
    public $beginning;
    public $insertId;
    public $database;
    public $lastsql;

    public function __construct($config = [])
    {
        $this->database = $config;
        $st = "{$this->database['db_type']}:host={$this->database['db_host']};port={$this->database['db_port']};dbname={$this->database['db_name']};charset={$this->database['db_charset']}";
        $ex = array();
        if (isset($this->database['pconnect']) && $this->database['pconnect'] === true) {
            $ex[\PDO::ATTR_PERSISTENT] = true;
        }
        try {
            $this->pdo = new \PDO($st, $this->database['db_user'], $this->database['db_pwd']);
        } catch (\PDOException $e) {
            throw new \PdoException($e->getMessage());
        }

        $this->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
        $this->pdo->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false);
        $this->pdo->setAttribute(\PDO::NULL_TO_STRING, true);
    }

    public function query($statement, array $data = array())
    {
        if ($this->closeSql($statement, $data)) {
            return 0;
        }
        $pre = $this->pdo->prepare($statement);
        $error = 'success';
        if ($pre === false) {
            $error = $this->pdo->errorInfo();$error = $error[2];
            if (Container::get('app')->app_debug()) throw new \PDOException($error);
        }
        $this->insertId = $this->pdo->lastInsertId();
        $data2 = $pre->execute($data);
        $this->convertSql($statement, $data, $error);
        return $data2;

    }

    public function fetch($statement, array $data = array())
    {
        if ($this->closeSql($statement, $data)) {
            return 0;
        }
        $pre = $this->pdo->prepare($statement, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY));
        $error = 'success';
        if ($pre === false) {
            $error = $this->pdo->errorInfo();$error = $error[2];
            if (Container::get('app')->app_debug()) throw new \PDOException($error);
        }
        $pre->execute($data);
        $this->convertSql($statement, $data, $error);
        return $pre->fetch(\PDO::FETCH_ASSOC);
    }

    public function fetchall($statement, array $data = array())
    {
        if ($this->closeSql($statement, $data)) {
            return 0;
        }
        $sth = $this->pdo->prepare($statement, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY));
        $error = 'success';
        if ($sth === false) {
            $error = $this->pdo->errorInfo();$error = $error[2];
            if (Container::get('app')->app_debug()) throw new \PDOException($error);
        }
        $sth->execute($data);
        $this->convertSql($statement, $data, $error);
        return $sth->fetchAll(\PDO::FETCH_ASSOC);
    }

    public function fetchcolumn($statement, array $data = array())
    {
        if ($this->closeSql($statement, $data)) {
            return 0;
        }
        $pre = $this->pdo->prepare($statement, array(\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY));
        $error = 'success';
        if ($pre === false) {
            $error = $this->pdo->errorInfo();$error = $error[2];
            if (Container::get('app')->app_debug()) throw new \PDOException($error);
        }
        $pre->execute($data);
        $this->convertSql($statement, $data, $error);
        return $pre->fetchColumn();
    }

    public function lastid()
    {
        return $this->insertId;
    }

    public function tablename($table)
    {
        return "`" . $this->database['db_prifx'] . $table . "`";
    }

    /**
     * 获取执行中的错误
     * @return array 返回错误信息
     */
    public function rollback()
    {
        if ($this->beginning) {
            $this->pdo->rollBack();
        }
    }

    public function getLastsql()
    {
        $error = $this->pdo->errorInfo();
        $this->lastsql['error'] = $error;
        return $this->lastsql;
    }

    public function begin()
    {
        $this->beginning = true;
        $this->pdo->beginTransaction();
    }

    public function commit()
    {
        try {
            $this->pdo->commit();
        } catch (\PDOException $e) {
            throw new \PDOException($e->getMessage());
        } // TODO: Change the autogenerated stub
    }
}
